package com.sky.service.impl;

import com.sky.constant.EmailTemplateConstant;
import com.sky.service.EmailService;
import com.sky.utils.EmailCreateAnAccountUtil;
import com.sky.utils.EmailUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.HashMap;

/**
 * @author majun
 * @package com.sky.service.impl
 * @date 2024/12/24 23:07
 */
@Service
@Slf4j
public class EmailServiceImpl implements EmailService {

    @Autowired
    private EmailCreateAnAccountUtil emailCreateAnAccountUtil;

    @Autowired
    private EmailUtil emailUtil;

    @Autowired
    private TemplateEngine templateEngine;

    /**
     * 发送验证码邮件
     *
     * @param userEmail 用户邮箱
     * @param userName 用户名
     * @param permissionName 用户正在进行的操作名称(如:修改密码、删除账号等)
     * @param verificationCode 验证码
     */
    @Override
    public void sendVerificationCodeEmail(String userEmail, String userName, String permissionName, String verificationCode) {
        try {
            // 创建模板上下文
            Context context = new Context();
            context.setVariable("name", userName);
            context.setVariable("permissionName", permissionName);
            context.setVariable("verificationCode", verificationCode);

            // 渲染模板
            String emailContent = templateEngine.process(EmailTemplateConstant.VERIFICATION_CODE_TEMPLATE, context);

            // 使用线程池异步发送邮件
            ExecutorService executor = Executors.newFixedThreadPool(10);
            try {
                executor.submit(() -> {
                    try {
                        emailUtil.sendEmail(userEmail, "验证码通知", emailContent);
                        log.info("验证码邮件发送成功，接收者：{}，操作：{}", userEmail, permissionName);
                    } catch (Exception e) {
                        log.error("验证码邮件发送失败", e);
                        throw new RuntimeException("验证码邮件发送失败", e);
                    }
                });
            } finally {
                executor.shutdown();
            }
        } catch (Exception e) {
            log.error("验证码邮件处理失败", e);
            throw new RuntimeException("验证码邮件处理失败", e);
        }
    }

    /**
     * 借阅图书逾期提醒邮件
     *
     * @param userEmail   用户邮箱
     * @param userName    用户名
     * @param bookName    书名
     * @param borrowDate  借阅日期
     * @param dueDate     应还日期
     * @param overdueDays 逾期天数
     * @param nowData     目前时间
     */
    public void sendOverdueReminderEmail(String userEmail,
                                         String userName,
                                         String bookName,
                                         String borrowDate,
                                         String dueDate,
                                         Integer overdueDays,
                                         String nowData) {
        // 构建变量Map
        Map<String, Object> variables = new HashMap<>();
        variables.put("userName", userName);
        variables.put("bookName", bookName);
        variables.put("borrowDate", borrowDate);
        variables.put("dueDate", dueDate);
        variables.put("overdueDays", overdueDays);
        variables.put("nowData", nowData);

        //将数据导入email模版
        String email = emailCreateAnAccountUtil.renderTemplate(EmailTemplateConstant.OVERDUE_REMINDER_TEMPLATE, variables);

        ExecutorService executor = Executors.newFixedThreadPool(10);
        try {
            executor.submit(() -> {
                try {
                    emailUtil.sendEmail(userEmail, EmailTemplateConstant.OVERDUE_REMINDER_TEMPLATE_NAME, email);
                } catch (Exception e) {
                    // 添加日志记录
                    log.error("邮件发送失败", e);
                }
            });
        } finally {
            executor.shutdown();
        }
    }

    /**
     * 借阅申请被拒绝提醒邮件
     *
     * @param userEmail 用户邮箱
     * @param userName 用户名
     * @param bookName 书名
     * @param requestDate 申请日期
     * @param reviewDate 审核日期
     * @param rejectReason 拒绝原因
     * @param nowData 当前日期
     */
    public void sendRejectLoanRequestEmail(String userEmail,
                                         String userName,
                                         String bookName,
                                         String requestDate,
                                         String reviewDate,
                                         String rejectReason,
                                         String nowData) {
        // 构建变量Map
        Map<String, Object> variables = new HashMap<>();
        variables.put("userName", userName);
        variables.put("bookName", bookName);
        variables.put("requestDate", requestDate);
        variables.put("reviewDate", reviewDate);
        variables.put("rejectReason", rejectReason);
        variables.put("nowData", nowData);

        //将数据导入email模版
        String email = emailCreateAnAccountUtil.renderTemplate(EmailTemplateConstant.REJECT_LOAN_REQUEST_TEMPLATE, variables);

        ExecutorService executor = Executors.newFixedThreadPool(10);
        try {
            executor.submit(() -> {
                try {
                    emailUtil.sendEmail(userEmail, EmailTemplateConstant.REJECT_LOAN_REQUEST_TEMPLATE_NAME, email);
                } catch (Exception e) {
                    log.error("拒绝借阅申请邮件发送失败", e);
                }
            });
        } finally {
            executor.shutdown();
        }
    }

    /**
     * 发送重置密码验证码邮件
     * 验证码有效期为15分钟
     *
     * @param userEmail 用户邮箱
     * @param userName 用户名
     * @param verificationCode 验证码
     */
    @Override
    public void sendResetPasswordVerificationCode(String userEmail, String userName, String verificationCode) {
        try {
            // 创建模板上下文
            Context context = new Context();
            context.setVariable("name", userName);
            context.setVariable("permissionName", "重置密码");
            context.setVariable("verificationCode", verificationCode);

            // 渲染模板
            String emailContent = templateEngine.process(EmailTemplateConstant.VERIFICATION_CODE_TEMPLATE, context);

            // 使用线程池异步发送邮件
            ExecutorService executor = Executors.newFixedThreadPool(10);
            try {
                executor.submit(() -> {
                    try {
                        emailUtil.sendEmail(userEmail, "重置密码验证码", emailContent);
                        log.info("重置密码验证码邮件发送成功，接收者：{}", userEmail);
                    } catch (Exception e) {
                        log.error("重置密码验证码邮件发送失败", e);
                        throw new RuntimeException("重置密码验证码邮件发送失败", e);
                    }
                });
            } finally {
                executor.shutdown();
            }
        } catch (Exception e) {
            log.error("重置密码验证码邮件处理失败", e);
            throw new RuntimeException("重置密码验证码邮件处理失败", e);
        }
    }

    /**
     * 发送敏感操作验证码邮件
     *
     * @param userEmail 用户邮箱
     * @param userName 用户名
     * @param operationName 操作名称
     * @param verificationCode 验证码
     */
    @Override
    public void sendCaptchaEmail(String userEmail, String userName, String operationName, String verificationCode) {
        try {
            // 创建模板上下文
            Context context = new Context();
            context.setVariable("name", userName);
            context.setVariable("permissionName", operationName);
            context.setVariable("verificationCode", verificationCode);

            // 渲染模板
            String emailContent = templateEngine.process(EmailTemplateConstant.CAPTCHA_TEMPLATE, context);

            // 使用线程池异步发送邮件
            ExecutorService executor = Executors.newFixedThreadPool(10);
            try {
                executor.submit(() -> {
                    try {
                        emailUtil.sendEmail(userEmail, EmailTemplateConstant.CAPTCHA_TEMPLATE_NAME, emailContent);
                        log.info("敏感操作验证码邮件发送成功，接收者：{}，操作：{}", userEmail, operationName);
                    } catch (Exception e) {
                        log.error("敏感操作验证码邮件发送失败", e);
                        throw new RuntimeException("敏感操作验证码邮件发送失败", e);
                    }
                });
            } finally {
                executor.shutdown();
            }
        } catch (Exception e) {
            log.error("敏感操作验证码邮件处理失败", e);
            throw new RuntimeException("敏感操作验证码邮件处理失败", e);
        }
    }

}
